package com.ceuer.demo.juc.single;

/**
 * 单例模式-DCL 懒汉式
 */
public class LazyMan2 {
	private LazyMan2(){
		System.out.println(Thread.currentThread().getName()+"\t ok");
	}
	
	private static LazyMan2 LAZYMAN2;
	
	//双重检测锁模式的 懒汉式单例 DCL懒汉式
	//双重检测 if(LAZYMAN2 ==null) 有两次
	//锁 synchronized (LazyMan2.class)
	public static LazyMan2 getInstance(){
		if(LAZYMAN2 ==null){
			synchronized (LazyMan2.class){//同步锁class保证只有一个类同时在用
				if(LAZYMAN2 ==null){
					LAZYMAN2 =new LazyMan2();//虽然 不是一个原子性操作
					/*
						1、分配内存空间
						2、执行构造方法，初始化对象
						3、把这个对象指向这个空间
						tips:看起来是一个操作，实际是多个操作
						不是原子性就可以在代码自动重排的时候出现
						单线程A
							123
							132
						这两个顺序都是可以的，
						但是如果存在B线程，那么此时LazyMan2还没有完成构造的可能，
						所以需要再此优化
					 */
				}
			}
		}
		return LAZYMAN2;
	}
	
	public static void main(String[] args) {
		for (int i = 0; i < 10; i++) {
			new Thread(()->{
				LazyMan2.getInstance();
			}).start();
		}
	}
	
}
